import { getSbData, supabase } from "../base/supabase";

export async function getBaseList(table, params, opts = {}) {
  params._list = true;
  return getBaseInfo(table, params, opts);
}

export async function getBaseInfo(table, params, opts = {}) {
  let fields = "*";
  const selectOpts = {};
  let rangeFrom = -1;
  let rangeTo;
  let orderBy;
  let isDesc = false;
  const isRow = !params._list;
  const isTree = !!params._tree;
  let {
    _attributes,
    _attrs,
    _page,
    _limit = 10,
    _order = isTree ? "id asc" : "id desc",
  } = params;
  const attrs = _attributes || _attrs;
  if (attrs) {
    fields = attrs.join(",");
  }
  if (_page) {
    rangeFrom = (_page - 1) * _limit;
    rangeTo = _page * _limit - 1;
    selectOpts.count = "exact";
  }
  if (_order) {
    const arr = _order.split(/\s+/);
    orderBy = arr[0];
    isDesc = arr[1] == "desc";
  }
  let res = supabase.from(table).select(fields, selectOpts);
  for (const key in params) {
    if (/^_/.test(key)) {
      // console.log(table, key);
      continue;
    }
    res.eq(key, params[key]);
  }
  let { setRes } = opts;
  if (typeof opts == "function") setRes = opts;
  if (setRes) {
    setRes(res);
  }
  if (orderBy) {
    res.order(orderBy, {
      ascending: !isDesc,
    });
  }
  if (rangeFrom > -1) {
    res.range(rangeFrom, rangeTo);
  } else if (isRow) {
    res.limit(1);
  }
  res = await res;
  const list = getSbData(res);
  for (const it of list) {
    for (const key in it) {
      const mat = /(\w+)_at$/.exec(key);
      if (!mat) continue;
      const val = it[key];
      it[mat[1] + "_t"] = new Date(val).format();
    }
  }
  if (isRow) {
    return list[0];
  }
  if (isTree) {
    return getTree(list);
  }
  if (rangeFrom > -1) {
    return {
      items: list,
      total: res.count,
    };
  }
  return list;
}

function getTree(list) {
  const map = new Map(list.map((item) => [item.id, { ...item, children: [] }]));
  const tree = [];
  for (const item of list) {
    if (!item.pid) {
      // 根节点
      tree.push(map.get(item.id));
    } else {
      // 找到其父节点并添加到父节点的 children 中
      const parent = map.get(item.pid);
      if (parent) {
        parent.children.push(map.get(item.id));
      }
    }
  }
  return tree;
}
